package part3.c16_singleton.monostate_demo;

/**
 *  @see Turnstitle
 *  地铁十字转门的简单的有限状态机
 */
public class Test {

    public void setUp(){
        Turnstitle turnstitle = new Turnstitle();
        turnstitle.reset();
    }
    //重置完，应该是锁的/不报警的
    public void testInit(){
        Turnstitle t = new Turnstitle();
        assert t.locked();
        assert ! t.alarm();
    }

    /**
     * 这个方法体现出了monostate模式设计的精妙
     * 投币(coin()受当前状态不同而有不同的操作
     * 而调用者不需要知道细节
     */
    public void testCoin(){
        Turnstitle t = new Turnstitle();
        t.coin();//

        Turnstitle t1 = new Turnstitle();
        //静态是通用的，这里特意新建一个实例来验证
        assert ! t1.locked();
        assert ! t1.alarm();
        assert 1 == t1.coins();
    }

    public void testCoinAndPass(){
        Turnstitle t = new Turnstitle();
        t.coin();
        t.pass();

        Turnstitle t1 = new Turnstitle();
        assert t1.locked();
        //state 已经转成UNLOCKED
        assert !t1.alarm();
        assert 1 == t1.coins();
    }

    public void testTwoCoins(){
        Turnstitle t = new Turnstitle();
        t.coin();
        t.coin();

        Turnstitle t1 = new Turnstitle();
        assert ! t1.locked();
        assert 1 == t1.coins();
        assert 1 == t1.refunds();
        assert ! t1.alarm();
    }

    public void testPass(){
        Turnstitle t = new Turnstitle();
        t.pass();

        Turnstitle t1 = new Turnstitle();
        assert t1.alarm();
        assert t1.locked();
    }

    public void testCancelAlarm(){
        Turnstitle t = new Turnstitle();
        t.pass();
        t.coin();

        Turnstitle t1 = new Turnstitle();
        assert ! t1.alarm();
        assert ! t1.locked();
        assert 1 == t1.coins();
        assert 0 == t1.refunds();
    }

    public void testTwoOperations(){
        Turnstitle t = new Turnstitle();
        t.coin();
        t.pass();
        t.coin();
        assert ! t.locked();
        assert 2 == t.coins();
        t.pass();
        assert t.locked();
    }

    public static void main(String[] args){
        Test test = new Test();
        test.setUp();
        test.testInit();
        test.testCoin();
        test.testCoinAndPass();
        test.testTwoCoins();
        test.testPass();
        test.testCancelAlarm();
        test.testTwoOperations();
    }
}
